package com.fish.common.strategy.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.fish.common.config.MinioProperties;
import com.fish.common.strategy.FileUploadStrategy;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.http.Method;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * MinIO文件上传策略实现
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class MinioUploadStrategy implements FileUploadStrategy {
    
    private final MinioClient minioClient;
    private final MinioProperties minioProperties;
    
    @Override
    public Map<String, Object> upload(MultipartFile file, String path) throws Exception {
        // 确保桶存在
        ensureBucketExists();
        
        // 获取原始文件名
        String originalFilename = file.getOriginalFilename();
        
        // 生成新的文件名（使用UUID避免重复）
        String fileName = generateFileName(originalFilename);
        
        // 构建完整路径
        String fullPath = buildPath(path, fileName);
        
        // 上传文件
        try (InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(
                PutObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(fullPath)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build()
            );
        }
        
        // 获取文件访问URL
        String fileUrl = getFileUrl(fullPath);
        
        // 返回文件信息
        Map<String, Object> result = new HashMap<>();
        result.put("fileName", fileName);
        result.put("originalName", originalFilename);
        result.put("filePath", fullPath);
        result.put("fileUrl", fileUrl);
        result.put("fileSize", file.getSize());
        result.put("fileType", file.getContentType());
        result.put("bucketName", minioProperties.getBucketName());
        
        log.info("文件上传成功: {}", fullPath);
        return result;
    }
    
    @Override
    public boolean delete(String filePath) throws Exception {
        try {
            minioClient.removeObject(
                RemoveObjectArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .object(filePath)
                    .build()
            );
            log.info("文件删除成功: {}", filePath);
            return true;
        } catch (Exception e) {
            log.error("文件删除失败: {}", filePath, e);
            throw e;
        }
    }
    
    @Override
    public String getFileUrl(String filePath) throws Exception {
        // 生成预签名URL（7天有效期）
        return minioClient.getPresignedObjectUrl(
            GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(minioProperties.getBucketName())
                .object(filePath)
                .expiry(60 * 60 * 24 * 7) // 7天
                .build()
        );
    }
    
    @Override
    public String getType() {
        return "minio";
    }
    
    /**
     * 确保桶存在，不存在则创建
     */
    private void ensureBucketExists() throws Exception {
        boolean exists = minioClient.bucketExists(
            BucketExistsArgs.builder()
                .bucket(minioProperties.getBucketName())
                .build()
        );
        
        if (!exists) {
            minioClient.makeBucket(
                MakeBucketArgs.builder()
                    .bucket(minioProperties.getBucketName())
                    .build()
            );
            log.info("创建存储桶: {}", minioProperties.getBucketName());
        }
    }
    
    /**
     * 生成文件名
     */
    private String generateFileName(String originalFilename) {
        // 获取文件扩展名
        String extension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        // 使用UUID生成唯一文件名
        return IdUtil.simpleUUID() + extension;
    }
    
    /**
     * 构建文件路径（按日期分类）
     */
    private String buildPath(String path, String fileName) {
        // 如果path为空，使用日期作为路径
        if (path == null || path.trim().isEmpty()) {
            path = DateUtil.format(DateUtil.date(), "yyyy/MM/dd");
        }
        
        // 确保路径以/结尾
        if (!path.endsWith("/")) {
            path += "/";
        }
        
        return path + fileName;
    }
}
